package second;

import lombok.extern.slf4j.Slf4j;
import pojo.User;

/**
 * @author: ZhouBert
 * @date: 2020/7/24
 * @description:	Spring 是需要强化记忆的，不可像之前那样蜻蜓点水！
 * 本子项目是为了说明 Spring IoC 的本质！
 * 工厂 -> 反射工厂 -> 基于配置文件的反射工厂 -> 基于配置文件 + 模板模式 + 反射工厂！
 */
@Slf4j
public class TestApp {
	private String name = "张三";
	private String password = "z3";
	private User user = new User(name, password);


	/**
	 * V0
	 * 使用原始的方式完成业务- 注册+登陆
	 * 存在强耦合关系，因为
	 * UserService userService= new UserServiceImpl();
	 * 被硬编码。如果要进行修改，需要修改+重新编译！+重新部署
	 * TODO:--- 使用设计模式优化！（Spring 优势在于：巧妙地使用设计模式实现了架构的分层！）
	 * 工厂模式
	 */
	public void testOriginal(){
		UserService userService= new UserServiceImpl();
		userService.register(user);
		userService.login(name, password);
	}

	/**
	 * V1
	 * 使用简单工厂进行优化
	 * 这样只是将
	 * UserService userService= new UserServiceImpl();
	 * 转移到了
	 * MySimpleBeanFactory 类中
	 * 依然不能摆脱需求变动，进行修改，需要修改+重新编译！+重新部署 的过程！
	 * 于是再进一步优化！
	 * TODO:-- 使用【反射工厂】进行优化
	 * 【以前学习工厂时怎么没有把【工厂】+【反射】联系起来！】
	 */
	public void testSimpleFactory(){
		UserService userService = MySimpleBeanFactory.createUserService();
		userService.register(user);
		userService.login(name, password);
	}

	/**
	 * 终于构建了一个小型 BeanFactory ！
	 * 在 【反射工厂】 的基础上，通过读取外部的配置文件，创建服务类；
	 * 这样，就是需求发生变动，进行修改：只需要
	 * 1-加一个 second.impl.UserServiceImplNew  类，
	 * 2-添加包含该类的jar
	 * 3-修改配置文件
	 * 4-甚至不需要重新编译，放进去部署就可以了！
	 * -----
	 * 实现了一个 createUserService 后，考虑通用方法
	 * TODO:-- 抽象出共性生成通用方法！越来越像 Spring ApIoC 了！
	 */
	public void testFactory(){
		UserService userService = MyBeanFactory.createUserService();
		userService.register(user);
		userService.login(name, password);
	}

	/**
	 * 测试 工厂的通用方法!
	 * 成功了！
	 * TODO:总结一下：
	 * 1.定义类型（类）
	 * 2.通过配置文件的配置告知工厂（.properties）
	 * key=value
	 * 3.通过工厂获取类的对象
	 * Object ret = BeanFactory.getBean("key")
	 * TODO:关联到 Spring
	 * Spring 本质：【工厂】 ApplicationContext(applicationContext.xml)
	 */
	public void testCommonFactory(){
		String name ="userService";
		log.info("beans name : {}", name);
		UserService userService = (UserService)MyBeanFactory.getBean(name);
		userService.register(user);
		userService.login(name, password);
	}





	public static void main(String[] args) {
		TestApp testApp = new TestApp();
		testApp.testOriginal();
		log.info("==========");
		testApp.testSimpleFactory();
		log.info("==========");
		testApp.testFactory();
		log.info("==========");
		testApp.testCommonFactory();
	}
}
